<script setup lang="ts">
import { ref, watch, onMounted, nextTick } from "vue";
import { handleTree } from "@/utils/tree";
import { getKeyList, useResizeObserver, delay, subBefore } from "@pureadmin/utils";
import { getAllPermissions, getRolePermissions, assignPermissionsToRole } from "@/api/system";
import { message } from "@/utils/message";
import Check from "~icons/ep/check";
import Close from "~icons/ep/close";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { transformI18n } from "@/plugins/i18n";

const props = defineProps<{
  roleId: number;
  roleName: string;
  close?: Function; // 添加 close prop
}>();

const emit = defineEmits(["closeDialog"]); // 仍然保留，以防万一，但主要使用 close prop

const treeRef = ref(); // 组件内部维护自己的 treeRef
const treeData = ref([]);
const treeIds = ref([]);
const isExpandAll = ref(false);
const isSelectAll = ref(false);
const isLinkage = ref(false);
const treeSearchValue = ref("");
const treeHeight = ref(400); // 默认高度，实际会根据内容调整

const treeProps = {
  value: "id",
  label: "name",
  children: "children"
};

const iconClass = [
  "w-[22px]",
  "h-[22px]",
  "flex",
  "justify-center",
  "items-center",
  "outline-hidden",
  "rounded-[4px]",
  "cursor-pointer",
  "transition-colors",
  "hover:bg-[#0000000f]",
  "dark:hover:bg-[#ffffff1f]",
  "dark:hover:text-[#ffffffd9]"
];

const filterMethod = (query: string, node) => {
  return transformI18n(node.title)!.includes(query);
};

const onQueryChanged = (query: string) => {
  treeRef.value!.filter(query);
};

async function initPermissions() {
  // 获取所有权限
  const { data: allPermissions } = await getAllPermissions();
  treeData.value = handleTree(allPermissions);
  treeIds.value = getKeyList(allPermissions, "id");

  // 获取角色当前拥有的权限
  const { data: rolePermissions } = await getRolePermissions(props.roleId);
  const rolePermissionIds = rolePermissions.map(item => item.id);
  await nextTick(); // 确保 treeRef 已经渲染
  treeRef.value!.setCheckedKeys(rolePermissionIds);
}

async function handleSavePermissions() {
  const permission_ids = treeRef.value!.getCheckedKeys();
  const { code, message: msg } = await assignPermissionsToRole({
    role_id: props.roleId,
    permission_ids
  });
  if (code === 200) {
    message(msg, { type: "success" });
    props.close && props.close(); // 调用 close prop
  } else {
    message(msg, { type: "error" });
  }
}

onMounted(() => {
  initPermissions();
});

watch(isExpandAll, val => {
  val ? treeRef.value!.setExpandedKeys(treeIds.value) : treeRef.value!.setExpandedKeys([]);
});

watch(isSelectAll, val => {
  val ? treeRef.value!.setCheckedKeys(treeIds.value) : treeRef.value!.setCheckedKeys([]);
});
</script>

<template>
  <div class="permission-dialog">
    <div class="flex justify-between w-full px-3 pt-5 pb-4">
      <div class="flex">
        <span :class="iconClass">
          <IconifyIconOffline
            v-tippy="{
              content: '关闭'
            }"
            class="dark:text-white"
            width="18px"
            height="18px"
            :icon="Close"
            @click="props.close && props.close()"
          />
        </span>
        <span :class="[iconClass, 'ml-2']">
          <IconifyIconOffline
            v-tippy="{
              content: '保存菜单权限'
            }"
            class="dark:text-white"
            width="18px"
            height="18px"
            :icon="Check"
            @click="handleSavePermissions"
          />
        </span>
      </div>
      <p class="font-bold truncate">
        菜单权限
        {{ `${props.roleName ? `（${props.roleName}）` : ""}` }}
      </p>
    </div>
    <el-input
      v-model="treeSearchValue"
      placeholder="请输入菜单进行搜索"
      class="mb-1"
      clearable
      @input="onQueryChanged"
    />
    <div class="flex flex-wrap">
      <el-checkbox v-model="isExpandAll" label="展开/折叠" />
      <el-checkbox v-model="isSelectAll" label="全选/全不选" />
      <el-checkbox v-model="isLinkage" label="父子联动" />
    </div>
    <el-tree-v2
      ref="treeRef"
      show-checkbox
      :data="treeData"
      :props="treeProps"
      :height="treeHeight"
      :check-strictly="!isLinkage"
      :filter-method="filterMethod"
    >
      <template #default="{ node }">
        <span>{{ transformI18n(node.label) }}</span>
      </template>
    </el-tree-v2>
  </div>
</template>

<style scoped>
.permission-dialog {
  display: flex;
  flex-direction: column;
  height: 100%;
}
</style>
